package com.lotus.lqmp.service.common.aspect;

import com.lotus.platform.common.model.base.BaseResult;
import com.lotus.platform.common.model.enums.BusinessExceptionEnum;
import com.lotus.platform.common.model.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

/**
 * 全局异常处理
 * @author Liwei.Zhang3
 * @since 2022/01/06 13:41
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @Autowired
    protected MessageSource messageSource;

    @ExceptionHandler(Exception.class)
    public BaseResult<String> handleException(Exception e, HttpServletRequest request, HttpServletResponse response) {
        log.error("request {} failed", request.getRequestURI(), e);
        response.setStatus(HttpStatus.OK.value());
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        String msg;
        if (e instanceof BusinessException) { // 业务异常
            BusinessException businessException = (BusinessException)e;
            msg = messageSource.getMessage(String.valueOf(businessException.getCode()),
                businessException.getArgs(), businessException.getLocalizedMessage(), Locale.getDefault());
        } else if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException argumentNotValidException = (MethodArgumentNotValidException)e;
            msg = handleBindingResult(argumentNotValidException.getBindingResult());
        } else { // 系统异常
            BusinessExceptionEnum businessExceptionEnum = BusinessExceptionEnum.SYSTEM_ERROR;
            msg = messageSource.getMessage(String.valueOf(businessExceptionEnum.code()), null,
                businessExceptionEnum.message(), Locale.getDefault());
        }
        return BaseResult.fail(null, msg);
    }

    private String handleBindingResult(BindingResult bindingResult) {
        StringBuilder sb = new StringBuilder();
        sb.append("validation error for object '").append(bindingResult.getObjectName()).append("' ");
        for (ObjectError error : bindingResult.getAllErrors()) {
            sb.append("[");
            if (error instanceof FieldError) {
                sb.append("field '").append(((FieldError)error).getField()).append("': ");
            }
            sb.append(error.getDefaultMessage()).append("];");
        }
        return sb.substring(0, sb.length() - 1);
    }
}
